﻿using AutoMapper;
using Microsoft.AspNetCore.Http;
using RBACProject.Application.Menu.Dto;
using RBACProject.Domian;
using RBACProject.Domian.Enum;
using RBACProject.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using static System.Net.WebRequestMethods;

namespace RBACProject.Application.Menu
{
    /// <summary>
    /// 菜单服务层
    /// </summary>
    public class MenuService : IMenuService
    {
        private readonly IBaseRepository<MenuModel> Imenu;
       
        private readonly IHttpContextAccessor _http;


        private readonly MyDbContext Db;
        private IMapper Imapperinfo;


        public IBaseRepository<RoleMenuModel> Rolemenu { get; }

        public MenuService(IBaseRepository<MenuModel> imenu, IMapper imapperinfo, MyDbContext db, IBaseRepository<RoleMenuModel> rolemenu, IHttpContextAccessor Http)
        {
            Imenu = imenu;
            Imapperinfo = imapperinfo;
            Db = db;
            Rolemenu = rolemenu;
            _http = Http;
        }

        /// <summary>
        /// 获取菜单子节点(递归)
        /// </summary>dddd
        /// <param name="parentId"></param> 
        /// <returns></returns>
        public List<TreeDto> GetTreeInfo(int parentId)
        {
            //根据父级Id获取菜单信息
            var menus = Imenu.QueryAsnycAll().Where(x => x.ParentId == parentId && x.IsDeleted == false);
            //创建一个空的TreeDto列表，用于存储转换后的菜单信息。
            //实例化dto集合
            List<TreeDto> dto = new List<TreeDto>();
            //对查询到的菜单列表进行循环处理
            foreach (var item in menus.ToList())
            {
                //对于每一个菜单项，将其映射为TreeDto对象
                var data = Imapperinfo.Map<TreeDto>(item);
                //判断是否存在子节点。
                //如果存在子节点，则通过递归调用GetTreeInfo方法获取子节点的信息，并将其赋值给TreeDto对象的Children属性。如果不存在子节点，则将Children属性设置为null
                data.Children = GetTreeInfo(item.MenuId).Count() == 0 ? null : GetTreeInfo(item.MenuId);
                //将转换后的TreeDto对象添加到dto列表中。
                dto.Add(data);
            }
            return dto;
        }

        /// <summary>
        /// 获取菜单全部信息
        /// </summary>
        /// <returns></returns>
        public ResultDto<List<TreeDto>> GetMenuInfo()
        {
            var cols = Db.Database.BeginTransaction();
            try
            {
                using (cols)
                {
                    var data = Imenu.QueryAsnycAll();
                    cols.Commit();
                    return new ResultDto<List<TreeDto>>
                    {
                        Result = Result.Success,
                        Data = GetTreeInfo(0),
                    };
                }
            }
            catch (Exception)
            {
                cols.Rollback();
                throw;
            }
        }

        /// <summary>
        /// 获取菜单类型枚举  （目录，菜单，按钮）
        /// </summary>
        /// <returns></returns>
        public ResultDto<List<object>> GetMenuTypeInfo()
        {
            //使用事务
            using (var tran = Db.Database.BeginTransaction())
            {
                try
                {
                    //创建object类型的集合
                    List<object> obj = new List<object>();
                    //循环遍历
                    foreach (var item in Enum.GetValues<MenuType>())
                    {
                        //向集合添加值
                        obj.Add(new
                        {
                            label = item.ToString(),
                            value = item
                        });
                    }
                    tran.Commit();
                    return new ResultDto<List<object>>
                    {
                        Result = Result.Success,
                        Data = obj,
                    };
                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;
                }
            }
        }

        /// <summary>
        /// 菜单添加
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ResultDto<bool>> AddMeunInfo(CreateUpdateDto dto)
        {
            try
            {
                var menu = Imapperinfo.Map<CreateUpdateDto, MenuModel>(dto);
                menu.CreateTime = DateTime.Now;
                var info = await Imenu.InsertAsync(menu);
                return new ResultDto<bool> 
                { 
                    Result = Result.Success,
                    Message="添加成功！",
                };
            }
            catch (Exception)
            {
                return new ResultDto<bool> 
                { 
                    Result = Result.Failure,
                    Message = "添加失败！",
                };
            }
        }

        /// <summary>
        /// 菜单逻辑删除
        /// </summary>
        /// <param name="id">主键id</param>
        /// <returns></returns>
        public async Task<ResultDto<int>> DeleteMenu(int id)
        {
            var entity = await Imenu.QueryAsnycEntity(x=>x.ParentId==id);
            //判断是否有子菜单
            if (entity == null) 
            {
                return new ResultDto<int>
                {
                    Result = Result.Failure,
                    Message = "当前菜单有子信息,不能删除",
                };
            }
            //修改删除状态
            entity.IsDeleted = true;
            var data = await Imenu.UpdateAsnyc(entity);
            if (data.IsDeleted == true)
            {
                return new ResultDto<int>
                {
                    Result = Result.Success,
                    Message = "删除成功",
                };
            }
            else
            {
                return new ResultDto<int>
                {
                    Result = Result.Failure,
                    Message = "删除失败",
                };
            }
        }



        /// <summary>
        /// 通过Id获取菜单一条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultDto<MenuModel>> GetMenuInfoById(int id)
        {
            var data = await Imenu.QueryAsnycById(id);
            return new ResultDto<MenuModel>
            {
                Result = Result.Success,
                Data = data,
            };
        }

        /// <summary>
        /// 菜单编辑
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultDto<MenuModel>> UpdateMenuInfo(MenuModel model)
        {
            try
            {
                var data = await Imenu.UpdateAsnyc(model);
                return new ResultDto<MenuModel>
                {
                    Result = Result.Success,  
                    Message = "菜单编辑成功！",
                };
            }
            catch (Exception)
            {
                return new ResultDto<MenuModel>
                {
                    Result = Result.Failure,
                    Message = "菜单编辑失败！",
                };
            }     
        }

        /// <summary>
        /// 根据登陆的用户角色获取可访问的菜单信息
        /// </summary>
        /// <returns></returns>
        public ResultDto<List<MenuModel>> GetMenuRoute()
        {
            //现根据上下文查到登陆用户的角色  字符串数组转成int数组 
            IEnumerable<Claim> claims = _http.HttpContext.User.Claims;
            
            int[] roleIdarr = Array.ConvertAll(claims.First(x => x.Type == ClaimTypes.Role)
                .Value.Split(','), a => Convert.ToInt32(a));
            //联查拿角色的int数组去联查获取菜单权限
            var list = (from m in Imenu.QueryAsnycAll()    
                        join rm in Rolemenu.QueryAsnycAll()
                        on m.MenuId equals rm.MenuId
                        where roleIdarr.Contains(rm.RoleId)
                        select m).ToList();
            //返回
            return new ResultDto<List<MenuModel>>
            {
                Result = Result.Success,
                Data = list
            };
        }

    }
}
